package com.cardcaptorsakura.model.dto;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Size;
import java.util.List;

/**
 * 多模态输出请求DTO
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class MultiModalOutputRequest {

    /**
     * 请求ID
     */
    private String requestId;

    /**
     * 用户ID
     */
    @NotBlank(message = "用户ID不能为空")
    private String userId;

    /**
     * 输出模式列表
     */
    @NotEmpty(message = "输出模式不能为空")
    private List<OutputMode> outputModes;

    /**
     * 输入文本
     */
    @NotBlank(message = "输入文本不能为空")
    @Size(max = 4000, message = "输入文本长度不能超过4000字符")
    private String inputText;

    /**
     * 图像生成提示词
     */
    private String imagePrompt;

    /**
     * 图像宽度
     */
    private Integer imageWidth;

    /**
     * 图像高度
     */
    private Integer imageHeight;

    /**
     * 图像风格
     */
    private String imageStyle;

    /**
     * 语音文本（如果与输入文本不同）
     */
    private String voiceText;

    /**
     * 声音类型
     */
    private String voice;

    /**
     * 语音速度
     */
    private Double voiceSpeed;

    /**
     * 语音格式
     */
    private String voiceFormat;

    /**
     * 处理选项
     */
    @Builder.Default
    private ProcessingOptions options = new ProcessingOptions();

    /**
     * 优先级（1-10）
     */
    @Builder.Default
    private Integer priority = 5;

    /**
     * 超时时间（秒）
     */
    @Builder.Default
    private Integer timeout = 120;

    /**
     * 是否异步处理
     */
    @Builder.Default
    private Boolean async = false;

    /**
     * 回调URL（异步处理时使用）
     */
    private String callbackUrl;

    /**
     * 额外参数
     */
    private java.util.Map<String, Object> extraParams;

    /**
     * 输出模式枚举
     */
    public enum OutputMode {
        TEXT,       // 文本输出
        IMAGE,      // 图像输出
        VOICE,      // 语音输出
        COMBINED    // 组合输出（文本+图像+语音）
    }

    /**
     * 处理选项
     */
    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    public static class ProcessingOptions {
        /**
         * 是否使用记忆系统
         */
        @Builder.Default
        private Boolean useMemory = true;

        /**
         * 是否保存到记忆
         */
        @Builder.Default
        private Boolean saveToMemory = true;

        /**
         * 是否启用内容过滤
         */
        @Builder.Default
        private Boolean enableContentFilter = true;

        /**
         * 是否启用质量检查
         */
        @Builder.Default
        private Boolean enableQualityCheck = true;

        /**
         * 是否生成缩略图（图像）
         */
        @Builder.Default
        private Boolean generateThumbnail = true;

        /**
         * 是否生成波形数据（语音）
         */
        @Builder.Default
        private Boolean generateWaveform = false;

        /**
         * 是否启用并行处理
         */
        @Builder.Default
        private Boolean enableParallelProcessing = true;

        /**
         * 最大重试次数
         */
        @Builder.Default
        private Integer maxRetries = 3;

        /**
         * 重试间隔（毫秒）
         */
        @Builder.Default
        private Integer retryInterval = 1000;

        /**
         * 是否启用缓存
         */
        @Builder.Default
        private Boolean enableCache = true;

        /**
         * 缓存过期时间（秒）
         */
        @Builder.Default
        private Integer cacheExpiration = 3600;

        /**
         * 输出质量级别
         */
        @Builder.Default
        private QualityLevel qualityLevel = QualityLevel.STANDARD;

        /**
         * 是否启用个性化
         */
        @Builder.Default
        private Boolean enablePersonalization = true;

        /**
         * 个性化强度（0.0-1.0）
         */
        @Builder.Default
        private Double personalizationIntensity = 0.7;
    }

    /**
     * 质量级别枚举
     */
    public enum QualityLevel {
        LOW,        // 低质量，快速处理
        STANDARD,   // 标准质量
        HIGH,       // 高质量
        PREMIUM     // 顶级质量，处理时间较长
    }

    /**
     * 检查是否包含文本输出
     */
    public boolean hasTextOutput() {
        return outputModes != null && 
               (outputModes.contains(OutputMode.TEXT) || outputModes.contains(OutputMode.COMBINED));
    }

    /**
     * 检查是否包含图像输出
     */
    public boolean hasImageOutput() {
        return outputModes != null && 
               (outputModes.contains(OutputMode.IMAGE) || outputModes.contains(OutputMode.COMBINED));
    }

    /**
     * 检查是否包含语音输出
     */
    public boolean hasVoiceOutput() {
        return outputModes != null && 
               (outputModes.contains(OutputMode.VOICE) || outputModes.contains(OutputMode.COMBINED));
    }

    /**
     * 检查是否为组合输出
     */
    public boolean isCombinedOutput() {
        return outputModes != null && outputModes.contains(OutputMode.COMBINED);
    }

    /**
     * 获取预估处理时间（秒）
     */
    public int getEstimatedProcessingTime() {
        int baseTime = 0;
        
        if (hasTextOutput()) {
            baseTime += 5; // 文本生成约5秒
        }
        
        if (hasImageOutput()) {
            baseTime += 15; // 图像生成约15秒
        }
        
        if (hasVoiceOutput()) {
            // 根据文本长度估算语音合成时间
            String textForVoice = voiceText != null ? voiceText : inputText;
            int charCount = textForVoice != null ? textForVoice.length() : 0;
            baseTime += Math.max(3, charCount / 100); // 每100字符约1秒，最少3秒
        }
        
        // 根据质量级别调整时间
        if (options != null && options.getQualityLevel() != null) {
            switch (options.getQualityLevel()) {
                case LOW:
                    baseTime = (int) (baseTime * 0.7);
                    break;
                case HIGH:
                    baseTime = (int) (baseTime * 1.5);
                    break;
                case PREMIUM:
                    baseTime = (int) (baseTime * 2.0);
                    break;
                default:
                    // STANDARD - 不调整
                    break;
            }
        }
        
        // 如果启用并行处理，时间可以减少
        if (options != null && options.getEnableParallelProcessing() && 
            outputModes != null && outputModes.size() > 1) {
            baseTime = (int) (baseTime * 0.8);
        }
        
        return Math.max(baseTime, 5); // 最少5秒
    }

    /**
     * 验证请求参数
     */
    public boolean isValid() {
        if (userId == null || userId.trim().isEmpty()) {
            return false;
        }
        
        if (outputModes == null || outputModes.isEmpty()) {
            return false;
        }
        
        if (inputText == null || inputText.trim().isEmpty()) {
            return false;
        }
        
        // 如果包含图像输出，检查图像相关参数
        if (hasImageOutput() && imagePrompt == null) {
            // 如果没有专门的图像提示词，可以使用输入文本
            imagePrompt = inputText;
        }
        
        return true;
    }

    /**
     * 获取输出模式描述
     */
    public String getOutputModeDescription() {
        if (outputModes == null || outputModes.isEmpty()) {
            return "无";
        }
        
        java.util.List<String> descriptions = new java.util.ArrayList<>();
        for (OutputMode mode : outputModes) {
            switch (mode) {
                case TEXT:
                    descriptions.add("文本");
                    break;
                case IMAGE:
                    descriptions.add("图像");
                    break;
                case VOICE:
                    descriptions.add("语音");
                    break;
                case COMBINED:
                    descriptions.add("组合输出");
                    break;
            }
        }
        
        return String.join(", ", descriptions);
    }

    /**
     * 创建文本生成请求
     */
    public ChatRequest toChatRequest() {
        return ChatRequest.builder()
                .userId(userId)
                .text(inputText)
                .options(options)
                .build();
    }

    /**
     * 创建图像生成请求
     */
    public ImageGenerationRequest toImageGenerationRequest() {
        return ImageGenerationRequest.builder()
                .userId(userId)
                .prompt(imagePrompt != null ? imagePrompt : inputText)
                .width(imageWidth)
                .height(imageHeight)
                .style(imageStyle)
                .requestId(requestId)
                .build();
    }

    /**
     * 创建语音合成请求
     */
    public VoiceSynthesisRequest toVoiceSynthesisRequest() {
        return VoiceSynthesisRequest.builder()
                .userId(userId)
                .text(voiceText != null ? voiceText : inputText)
                .voice(voice)
                .speed(voiceSpeed)
                .format(voiceFormat)
                .requestId(requestId)
                .async(async)
                .callbackUrl(callbackUrl)
                .build();
    }
}